home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / dev / src / expat-src.lha / expat-1.95.2 / xmlwf / xmlfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-25  |  4.7 KB  |  227 lines

  1. /*
  2. Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
  3. See the file COPYING for copying permission.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stddef.h>
  9. #include <string.h>
  10. #include <fcntl.h>
  11. #ifndef AMIGA
  12. #include "expat.h"
  13. #else
  14. #include <exec/types.h>
  15. #include <exec/memory.h>
  16. #include <expat/expat.h>
  17. #include <proto/exec.h>
  18. #include <proto/expat.h>
  19. #endif
  20.  
  21. #include "xmlfile.h"
  22. #include "xmltchar.h"
  23. #include "filemap.h"
  24.  
  25. #ifdef _MSC_VER
  26. #include <io.h>
  27. #endif
  28.  
  29. #ifdef _POSIX_SOURCE
  30. #include <unistd.h>
  31. #endif
  32.  
  33. #ifndef O_BINARY
  34. #ifdef _O_BINARY
  35. #define O_BINARY _O_BINARY
  36. #else
  37. #define O_BINARY 0
  38. #endif
  39. #endif
  40.  
  41. #ifdef _DEBUG
  42. #define READ_SIZE 16
  43. #else
  44. #define READ_SIZE (1024*8)
  45. #endif
  46.  
  47.  
  48.  
  49. typedef struct {
  50.   XML_Parser parser;
  51.   int *retPtr;
  52. } PROCESS_ARGS;
  53.  
  54. static
  55. void reportError(XML_Parser parser, const XML_Char *filename)
  56. {
  57.   int code = XML_GetErrorCode(parser);
  58.   const XML_Char *message = XML_ErrorString(code);
  59.   if (message)
  60.     ftprintf(stdout, T("%s:%d:%d: %s\n"),
  61.          filename,
  62.          XML_GetErrorLineNumber(parser),
  63.          XML_GetErrorColumnNumber(parser),
  64.          message);
  65.   else
  66.     ftprintf(stderr, T("%s: (unknown message %d)\n"), filename, code);
  67. }
  68.  
  69. static
  70. void processFile(const void *data,
  71.          size_t size,
  72.          const XML_Char *filename,
  73.          void *args)
  74. {
  75.   XML_Parser parser = ((PROCESS_ARGS *)args)->parser;
  76.   int *retPtr = ((PROCESS_ARGS *)args)->retPtr;
  77.   if (!XML_Parse(parser, data, size, 1)) {
  78.     reportError(parser, filename);
  79.     *retPtr = 0;
  80.   }
  81.   else
  82.     *retPtr = 1;
  83. }
  84.  
  85. #ifdef WIN32
  86.  
  87. static
  88. int isAsciiLetter(XML_Char c)
  89. {
  90.   return (T('a') <= c && c <= T('z')) || (T('A') <= c && c <= T('Z'));
  91. }
  92.  
  93. #endif /* WIN32 */
  94.  
  95. static
  96. const XML_Char *resolveSystemId(const XML_Char *base, const XML_Char *systemId, XML_Char **toFree)
  97. {
  98.   XML_Char *s;
  99.   *toFree = 0;
  100.   if (!base
  101.       || *systemId == T('/')
  102. #ifdef WIN32
  103.       || *systemId == T('\\')
  104.       || (isAsciiLetter(systemId[0]) && systemId[1] == T(':'))
  105. #endif
  106.      )
  107.     return systemId;
  108.   *toFree = (XML_Char *)malloc((tcslen(base) + tcslen(systemId) + 2)*sizeof(XML_Char));
  109.   if (!*toFree)
  110.     return systemId;
  111.   tcscpy(*toFree, base);
  112.   s = *toFree;
  113.   if (tcsrchr(s, T('/')))
  114.     s = tcsrchr(s, T('/')) + 1;
  115. #ifdef WIN32
  116.   if (tcsrchr(s, T('\\')))
  117.     s = tcsrchr(s, T('\\')) + 1;
  118. #endif
  119.   tcscpy(s, systemId);
  120.   return *toFree;
  121. }
  122.  
  123. static
  124. int externalEntityRefFilemap(XML_Parser parser,
  125.                  const XML_Char *context,
  126.                  const XML_Char *base,
  127.                  const XML_Char *systemId,
  128.                  const XML_Char *publicId)
  129. {
  130.   int result;
  131.   XML_Char *s;
  132.   const XML_Char *filename;
  133.   XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
  134.   PROCESS_ARGS args;
  135.   args.retPtr = &result;
  136.   args.parser = entParser;
  137.   filename = resolveSystemId(base, systemId, &s);
  138.   XML_SetBase(entParser, filename);
  139.   if (!filemap(filename, processFile, &args))
  140.     result = 0;
  141.   free(s);
  142.   XML_ParserFree(entParser);
  143.   return result;
  144. }
  145.  
  146. static
  147. int processStream(const XML_Char *filename, XML_Parser parser)
  148. {
  149.   int fd = topen(filename, O_BINARY|O_RDONLY);
  150.   if (fd < 0) {
  151.     tperror(filename);
  152.     return 0;
  153.   }
  154.   for (;;) {
  155.     int nread;
  156.     char *buf = XML_GetBuffer(parser, READ_SIZE);
  157.     if (!buf) {
  158.       close(fd);
  159.       ftprintf(stderr, T("%s: out of memory\n"), filename);
  160.       return 0;
  161.     }
  162.     nread = read(fd, buf, READ_SIZE);
  163.     if (nread < 0) {
  164.       tperror(filename);
  165.       close(fd);
  166.       return 0;
  167.     }
  168.     if (!XML_ParseBuffer(parser, nread, nread == 0)) {
  169.       reportError(parser, filename);
  170.       close(fd);
  171.       return 0;
  172.     }
  173.     if (nread == 0) {
  174.       close(fd);
  175.       break;;
  176.     }
  177.   }
  178.   return 1;
  179. }
  180.  
  181. static
  182. int externalEntityRefStream(XML_Parser parser,
  183.                 const XML_Char *context,
  184.                 const XML_Char *base,
  185.                 const XML_Char *systemId,
  186.                 const XML_Char *publicId)
  187. {
  188.   XML_Char *s;
  189.   const XML_Char *filename;
  190.   int ret;
  191.   XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
  192.   filename = resolveSystemId(base, systemId, &s);
  193.   XML_SetBase(entParser, filename);
  194.   ret = processStream(filename, entParser);
  195.   free(s);
  196.   XML_ParserFree(entParser);
  197.   return ret;
  198. }
  199.  
  200. int XML_ProcessFile(XML_Parser parser,
  201.             const XML_Char *filename,
  202.             unsigned flags)
  203. {
  204.   int result;
  205.  
  206.   if (!XML_SetBase(parser, filename)) {
  207.     ftprintf(stderr, T("%s: out of memory"), filename);
  208.     exit(1);
  209.   }
  210.  
  211.   if (flags & XML_EXTERNAL_ENTITIES)
  212.       XML_SetExternalEntityRefHandler(parser,
  213.                                   (flags & XML_MAP_FILE)
  214.                       ? externalEntityRefFilemap
  215.                       : externalEntityRefStream);
  216.   if (flags & XML_MAP_FILE) {
  217.     PROCESS_ARGS args;
  218.     args.retPtr = &result;
  219.     args.parser = parser;
  220.     if (!filemap(filename, processFile, &args))
  221.       result = 0;
  222.   }
  223.   else
  224.     result = processStream(filename, parser);
  225.   return result;
  226. }
  227.